/*
 * LinkedList.cpp
 *
 *  Created on: Jan 25, 2012
 *      Author: beebe
 */

#include "LinkedList.h"

LinkedList::LinkedList(): first(NULL),last(NULL),size(0){}
LinkedList::~LinkedList(){
	Clear();
}
//!  Copy constructor.  Makes a complete copy of its argument
LinkedList::LinkedList(const LinkedList & other):first(NULL),last(NULL),size(0){
	copy(other);
}
void LinkedList::copy(const LinkedList& other){
	Clear();
	LLNode * pointer = other.GetLast();
	while( pointer!=NULL){
		Insert(pointer->value,NULL);
		pointer = pointer->prev;
	}
}
LinkedList& LinkedList::operator =(const LinkedList & other){
	if(&other == this)
			return *this;
	copy(other);
	return *this;
}



bool LinkedList::IsEmpty() const{
	if (size==0)
		return true;
	else
		return false;
}
void LinkedList::Clear(){
	LLNode * start = GetFirst();
	while(start!=NULL){
		LLNode * temp = start;
		start = start->next;
		delete temp;
	}
	last = NULL;
	first = NULL;
	size = 0;
}
int LinkedList::GetSize() const{
	return size;
}
LLNode * LinkedList::GetFirst()const{
	return first;
}
LLNode * LinkedList::GetLast()const{
	return last;
}
//!  Inserts value v into the list after node n
//!
//!  @param v The new value being inserted
//!  @param n A node that is already in the list after which the new node should
//!      be inserted.
//!      If n is NULL, the new node should be inserted at the beginning of the list.
//!
//!  @return a pointer to the newly inserted node
LLNode * LinkedList::Insert(const std::string & v, LLNode * n = NULL){
	LLNode * current = first;
	if(n == NULL){
		LLNode * newNode;
		if(first!=NULL){
			newNode = new LLNode(v,NULL,NULL);
			first->prev = newNode;
			newNode->next = first;
		}else{
			newNode = new LLNode(v,NULL,NULL);
			last = newNode;
		}
		first = newNode;
		size++;
		return newNode;
	}
	while(current != NULL){
		if(current == n){
			LLNode * newNode = new LLNode(v,current,current->GetNext());
			if(current->next != NULL)
				current->next->prev = newNode;
			else
				last = newNode;
			current->next = newNode;
			size++;
			return newNode;
		}
		current = current->next;
	}
	return NULL;
}

//! Searches for the first occurrence of value v that appears in the list
//!   after node n
//!
//!  @param v The value being searched for
//!  @param n The node in the list after which the search should begin.
//!      If n is NULL, the list should be searched from the beginning.
//!
//!  @return a pointer to the node containing v, or NULL if v is not found
LLNode * LinkedList::Find(const std::string & v, LLNode * n) const{
	LLNode * current = first;
	bool beginSearch = false;
	if(n==NULL)
		beginSearch = true;
	while(current != NULL){
		//Only begin search after the given node
		if(current == n){
			beginSearch = true;
			current = current->next;
			continue;
		}
		if(beginSearch == true && current->value==v){
			return current;
		}
		current = current->next;
	}
	return NULL;
}

//!  Removes node n from the list
//!
//!  @param n The node being removed from the list
void LinkedList::Remove(LLNode * n){
	LLNode * current = first;
	while(current != NULL){
		if(current == n){
			if(current->prev!=NULL)
				current->prev->next = current->next;
			else
				first = current->next;
			if(current->next!=NULL)
				current->next->prev = current->prev;
			else
				last = current->prev;
			size--;;
			delete(current);
			break;

		}
		current = current->next;
	}
	return;
}

